import java.util.Scanner;

public class day230519 {
    // 顺时针打印矩阵
    public int[] clockwisePrint(int[][] mat, int n, int m) {
        int n1 = 0;
        int n2 = n - 1;
        int m1 = 0;
        int m2 = m - 1;
        int[] ret = new int[n * m];
        int j = 0;
        while (n1 <= n2 && m1 <= m2) {
            // 最上边一行，从左到右
            for (int i = m1; i <= m2; ++i) {
                ret[j++] = mat[n1][i];
            }

            // 最右边一列，从上到下
            for (int i = n1 + 1; i <= n2; ++i) {
                ret[j++] = mat[i][m2];
            }

            // 最下边一行，从右到左
            if (n1 < n2) {
                // 如果只剩下一行, 这个就不打印了, 上边已经打印过了
                for (int i = m2 - 1; i >= m1; --i) {
                    ret[j++] = mat[n2][i];
                }
            }

            // 最左边一列，从下到上
            if (m1 < m2) {
                // 如果只剩下一列, 这个就不打印了, 右边已经打印过了
                for (int i = n2 - 1; i > n1; --i) {
                    ret[j++] = mat[i][m1];
                }
            }

            m1++;
            m2--;
            n1++;
            n2--;
        }
        return ret;
    }

    // 蛇形矩阵
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextInt()) {
            int n = in.nextInt();
            int[][] a = new int[n][n];
            int count = 1, i = 0, j = 0;
            while (count <= n * n) {
                for (j = 0; i >= 0; i--, j++) {
                    if (i < n && j < n) {
                        a[i][j] = count++;
                    }
                }
                for (i = 0; j >= 0; j--, i++) {
                    if (i < n && j < n) {
                        a[i][j] = count++;
                    }
                }
            }
            for (int[] arr: a) {
                for (int x : arr) {
                    System.out.printf("%d ", x);
                }
                System.out.println();
            }
        }
    }

    // 左右最值最大差
    public int findMaxGap(int[] A, int n) {
        int max = 0;
        // 找到全局最大值
        for (int i = 0; i < n; ++i) {
            max = Math.max(max, A[i]);
        }
        // 左右部分的最大值, 要尽可能的小
        // 左部分一定包含 A[0], 右部分一定包含A[n -1]
        // 左部分最大值 >= A[0]
        // 右部分最大值 >= A[n - 1]
        // 要尽可能小的情况下, 就取 A[0], A[n - 1]
        // 全局最大值 减去 这两个的较小值
        max = max - Math.min(A[0], A[n - 1]);
        return max;
    }

    // 遍历每一个划分
    // 更新左边最大值
    // 遍历找右边最大值
    // 更新最大值
    public int findMaxGap1(int[] A, int n) {
        int max = 0;
        int leftMax = 0;
        for (int i = 0; i <= n - 2; ++i) {
            leftMax = Math.max(leftMax, A[i]);
            int rightMax = 0;
            for (int j = i + 1; j < n; ++j) {
                rightMax = Math.max(rightMax, A[j]);
            }
            max = Math.max(max, Math.abs(leftMax - rightMax));
        }
        return max;
    }
}
